/**
 * Copyright (C) 2013 DaiKit.com - daikit4gxt module (admin@daikit.com)
 *
 *         Project home : http://code.daikit.com/daikit4gxt
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.daikit.daikit4gxt.shared.bean;

import java.io.Serializable;
import java.util.Date;


/**
 * SafeDate class for wrapping Date and not having GWT to change it according to timezone. The wrapped date will be the
 * same on server side and client side.
 * 
 * @author tcaselli
 * @version $Revision$ Last modifier: $Author$ Last commit: $Date$
 */
public class SafeDate implements Serializable, Comparable<SafeDate>
{

	private static final long serialVersionUID = -4153752142478303183L;

	private int year = 1900;
	private int month = 0;
	private int dayInMonth = 0;
	private int hours = 0;
	private int minutes = 0;
	private int seconds = 0;

	/**
	 * Default constructor
	 */
	public SafeDate()
	{
		// Nothing done by default
	}

	/**
	 * Create a {@link SafeDate} with given parameters
	 * 
	 * @param year
	 *           the year
	 * @param month
	 *           the month (starting from 0 for January)
	 * @param dayInMonth
	 *           the day in month (starting from 1 to max 31)
	 */
	public SafeDate(final int year, final int month, final int dayInMonth)
	{
		this.year = year;
		this.month = month;
		this.dayInMonth = dayInMonth;
	}

	/**
	 * Create a {@link SafeDate} from given {@link Date} and clear time. (time will be 00:00:000)
	 * 
	 * @param date
	 *           the date
	 */
	public SafeDate(final Date date)
	{
		this(date, true);
	}

	/**
	 * Create a {@link SafeDate} from given {@link Date}. Clear time (time will be 00:00:000) if clearTime is true
	 * 
	 * @param date
	 *           the date
	 * @param clearTime
	 *           to clear time
	 */
	@SuppressWarnings("deprecation")
	public SafeDate(final Date date, final boolean clearTime)
	{
		this.year = date.getYear() + 1900;
		this.month = date.getMonth();
		this.dayInMonth = date.getDate();
		if (!clearTime)
		{
			this.hours = date.getHours();
			this.minutes = date.getMinutes();
			this.seconds = date.getSeconds();
		}
	}

	/**
	 * @return this {@link SafeDate} as a {@link Date}
	 */
	@SuppressWarnings("deprecation")
	public Date asDate()
	{
		final Date ret = new Date(year - 1900, month, dayInMonth);
		ret.setHours(hours);
		ret.setMinutes(minutes);
		ret.setSeconds(seconds);
		return ret;
	}

	@Override
	public String toString()
	{
		return year + "-" + (month + 1 < 10 ? "0" + (month + 1) : month + 1) + "-"
				+ (dayInMonth + 1 < 10 ? "0" + dayInMonth : dayInMonth) + " " + (hours < 10 ? "0" + hours : hours) + ":"
				+ (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds < 10 ? "0" + seconds : seconds);
	}

	@Override
	public int hashCode()
	{
		return super.hashCode();
	}

	@Override
	public int compareTo(final SafeDate o)
	{
		return o == null ? 1 : toString().compareTo(o.toString());
	}

	@Override
	public boolean equals(final Object obj)
	{
		return obj != null && toString().equals(obj.toString());
	}

	// -------------------------------------------------------------------------------------------
	// ------------ GETTERS / SETTERS
	// -------------------------------------------------------------------------------------------

	/**
	 * @return the year
	 */
	public int getYear()
	{
		return year;
	}

	/**
	 * @param year
	 *           the year to set
	 */
	public void setYear(final int year)
	{
		this.year = year;
	}

	// /**
	// * Returns the day of the week represented by this date. The
	// * returned value (<tt>0</tt> = Sunday, <tt>1</tt> = Monday,
	// * <tt>2</tt> = Tuesday, <tt>3</tt> = Wednesday, <tt>4</tt> =
	// * Thursday, <tt>5</tt> = Friday, <tt>6</tt> = Saturday)
	// * represents the day of the week.
	// *
	// * @return the day of the week represented by this date.
	// */
	// public int getDay() {
	// return day;
	// }
	// public void setDay(int day) {
	// this.day = day;
	// }

	/**
	 * Returns a number representing the month that contains or begins with the instant in time represented by this
	 * <tt>Date</tt> object. The value returned is between <code>0</code> and <code>11</code>, with the value
	 * <code>0</code> representing January.
	 * 
	 * @return the month represented by this date.
	 */
	public int getMonth()
	{
		return month;
	}

	/**
	 * @param month
	 *           the month to set
	 */
	public void setMonth(final int month)
	{
		this.month = month;
	}

	/**
	 * @return the dayInMonth
	 */
	public int getDayInMonth()
	{
		return dayInMonth;
	}

	/**
	 * @param dayInMonth
	 *           the dayInMonth to set
	 */
	public void setDayInMonth(final int dayInMonth)
	{
		this.dayInMonth = dayInMonth;
	}

	/**
	 * @return the hours
	 */
	public int getHours()
	{
		return hours;
	}

	/**
	 * @param hours
	 *           the hours to set
	 */
	public void setHours(final int hours)
	{
		this.hours = hours;
	}

	/**
	 * @return the minutes
	 */
	public int getMinutes()
	{
		return minutes;
	}

	/**
	 * @param minutes
	 *           the minutes to set
	 */
	public void setMinutes(final int minutes)
	{
		this.minutes = minutes;
	}

	/**
	 * @return the seconds
	 */
	public int getSeconds()
	{
		return seconds;
	}

	/**
	 * @param seconds
	 *           the seconds to set
	 */
	public void setSeconds(final int seconds)
	{
		this.seconds = seconds;
	}

}
